//
//  Networking.swift
//  suda
//
//  Created by youai on 2019/7/11.
//  Copyright © 2019年 youi. All rights reserved.
//

import Foundation
import Alamofire

struct NetworkingResult<T>{
    ///网络访问是否成功
    let success : Bool
    //成功访问的返回值
    let data : T?
    //网络访问失败的error对象
    let error : Error?
}

class Networking {
    
    private static var _sessionManager:SessionManager? = nil
    private static var _sessionManager_YI:[SessionManager] = []
    static var sessionManager:SessionManager {
        get{
            if _sessionManager==nil {
                let configuration = URLSessionConfiguration.default
                
                //尽量禁用缓存
                configuration.urlCache = nil
                configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
                
                //可能要改
                let headers = ["content-type":"application/json;charset=UTF-8"]
                configuration.httpAdditionalHeaders = headers
                
                //                configuration.networkServiceType = .default
                configuration.timeoutIntervalForRequest = 30
                configuration.timeoutIntervalForResource = 60
                configuration.allowsCellularAccess = true
                configuration.httpShouldSetCookies = true
                
                //使用keep-alive
                configuration.httpShouldUsePipelining = true
                
                _sessionManager = SessionManager(configuration: configuration)
            }
            return _sessionManager!
        }
    }

    
    ///默认使用post请求，获取String值
    static func queryString(urlStr:String,params:[String:Any]?,useGetMethod:Bool = false,queue: DispatchQueue? = nil, completion: @escaping (NetworkingResult<String>)->() ){
        let url = URL(string: urlStr)!
        sessionManager.request(url , method: useGetMethod ? .get : .post, parameters: params, encoding: JSONEncoding.default).responseString(queue:queue, encoding:.utf8) { (response) in
            let result = NetworkingResult(
                success: response.result.isSuccess,
                data: response.result.value,
                error: response.result.error)
            completion(result)
        }
    }
    
    static func formString(urlStr:String,params:[String:Any]?,useGetMethod:Bool = false,queue: DispatchQueue? = nil, completion: @escaping (NetworkingResult<String>)->() ){
        var sessionManager_YI:SessionManager {
            get{
                //时间戳转成字符串
                    func timeIntervalChangeToTimeStr(timeInterval:TimeInterval, dateFormat:String?) -> String {
                        let date = Date.init(timeIntervalSince1970: timeInterval)
                        let formatter = DateFormatter.init()
                        if dateFormat == nil {
                            formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
                        }else{
                            formatter.dateFormat = dateFormat
                        }
                        return formatter.string(from:date)
                    }
                
                /// 获取当前 秒级 时间戳 - 10位
                    func timeStamptoStr() -> String {
                        let timeInterval: TimeInterval = Date().timeIntervalSince1970
                        let t = Int64(round(timeInterval*1000))
                        return anyToString(t) ?? "00000000000"
                    }

                    /// 获取当前 毫秒级 时间戳 - 13位
                    func milliStamptoStr() -> String {
                        let timeInterval: TimeInterval = Date().timeIntervalSince1970
                        let millisecond = CLongLong(round(timeInterval*1000))
                        let str = anyToString(millisecond) ?? "00000000000273"
                        let sub1 = str.suffix(4)
                        return String(sub1)
                    }
                
                let timeStamp = timeStamptoStr() //timeIntervalChangeToTimeStr(timeInterval: Date().timeIntervalSince1970, dateFormat: nil)
                let milliStamp = milliStamptoStr()
                    let configuration = URLSessionConfiguration.default
                    
                    //尽量禁用缓存
                    configuration.urlCache = nil
                    configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
                    
                    var sign = "timestamp="+timeStamp+"&nonce="+milliStamp+"&secretKey=fe372ffe06fb497b96fce22d8fa770e6"
                    var paramsStr = ""
                    if let sortedKeys = params?.keys.sorted() {
                        for key in sortedKeys {
                            paramsStr += key
                            paramsStr += "="
                            paramsStr += (anyToString(params?[key]) ?? "")
                            paramsStr += "&"
                        }
                    }
                    sign = paramsStr + sign
                    
                    //可能要改
                    var headers = ["sign":sign.MD5,
                                   "timestamp":timeStamp,
                                   "nonce":milliStamp]
                    if let token = LocalStorage.getString(forKey: USER_IDENTITYTOKEN) {
                        headers.updateValue(token, forKey: "token")
                    }

                    print("header:\n" + (anyToString(headers.jsonString) ?? ""))
                    configuration.httpAdditionalHeaders = headers
                    
                    //                configuration.networkServiceType = .default
                    configuration.timeoutIntervalForRequest = 20
                    configuration.timeoutIntervalForResource = 60
                    configuration.allowsCellularAccess = true
                    configuration.httpShouldSetCookies = true
                    
                    //使用keep-alive
                    configuration.httpShouldUsePipelining = true
                return SessionManager(configuration: configuration)
            }
        }
        
        let url = URL(string: urlStr)!
        _sessionManager_YI.append(sessionManager_YI)
        _sessionManager_YI.last!.request(url , method: useGetMethod ? .get : .post, parameters: params).responseString(queue:queue) { (response) in
            let result = NetworkingResult(
                success: response.result.isSuccess,
                data: response.result.value,
                error: response.result.error)
            completion(result)
        }
        if _sessionManager_YI.count > 10 {
            _sessionManager_YI.remove(at: 0)
        }
    }

    ///使用DispatchQueue.global队列发送post请求，获取Json值
    ///默认使用post请求
    static func queryJson(urlStr:String,params:[String:Any]?,useGetMethod:Bool = false,queue: DispatchQueue? = nil ,completion: @escaping (NetworkingResult<[String:Any?]>)->() ){
        let url = URL(string: urlStr)!
        _ = sessionManager.request(url , method: useGetMethod ? .get : .post, parameters: params, encoding: JSONEncoding.default).responseJSON(queue: queue){ (response) in
            //如果返回值无法解析成json，则讲字符串返回
            var resultData = response.result.value as? [String:Any?]
            if resultData == nil && response.data != nil {
                resultData = ["_content":String(data: response.data!, encoding: .utf8)]
            }
            let result = NetworkingResult<[String:Any?]>(
                success: response.result.isSuccess,
                data: resultData,
                error: response.result.error)
            if response.result.value != nil && result.data == nil {
                fatalError("无法识别的请求返回格式：\n"+response.result.value.debugDescription)
            }
            
            completion(result)
        }
    }

}
